<?php
/**
 * User:ayou chow
 * Date: 2019-06-14
 * Time: 17:01
 */

namespace app\admin\controller;

use app\common\model\AdminLogModel;
use app\common\model\AdminModel;
use app\common\QcloudSTS;
use think\Controller;
use think\exception\HttpResponseException;
use think\facade\Cache;
use think\facade\Cookie;
use think\facade\Request;
use think\facade\Log;
use think\Response;
use think\Validate;

class BaseController extends Controller
{

    // 后台管理员信息
    protected $userinfo;
    protected $admin_id      = 0;
    protected $admin_name    = '';
    protected $admin_account = '';

    /**
     * 参数校验规则
     */
    protected $rules = [];

    protected $OPENSSL_KEY = 'meet';

    /**
     * 初始化操作
     */
    protected function initialize()
    {
        if (!$this->checkUser()) {
            $this->redirect(url('login/redirectpage'));
        }

        // google 身份验证检查
        $google_code_check = $this->getGoogleCodeCookie($this->userinfo->id, 1);
        if (!$google_code_check) {
            $this->redirect(url('login/index'));
        }

        if ((strpos(Request::action(), '_post') || Request::isPost()) && $this->userinfo->role->is_visitor) {
            $json     = json_encode(array("code" => "1", "msg" => "权限不足"));
            $response = Response::create($json);
            throw new HttpResponseException($response);
        }

        if (!$this->check_params()) {
            $json     = json_encode(array("code" => "1", "msg" => "参数不全"));
            $response = Response::create($json);
            throw new HttpResponseException($response);
        }
        $this->admin_id      = $this->userinfo->id;
        $this->admin_name    = $this->userinfo->name;
        $this->admin_account = $this->userinfo->account;
    }

    /**
     * 查询用户
     * @return bool
     */
    protected function checkUser()
    {
        $token = Cookie::get("token");
        $uid   = Cookie::get("uid");
        if (!$uid || !$token) {
            return false;
        }
        $this->userinfo = AdminModel::where(['id' => $uid, 'token' => $token, 'status' => 1])->with('role')->find();
        if ($this->userinfo) {
            return true;
        }
        return false;
    }

    /**
     * google secret cookie设置
     * @param $str
     * @param $uid
     */
    protected function setGoogleCodeCookie($str, $uid)
    {
        $str = time() . "_{$uid}_" . $str;
        Cookie::set("googlesecret", opensslEnCode($str));
    }

    /**
     *  google secret cookie获取
     * googlesecret 规则：时间戳_uid值_googlesecret值_1,最后一个1是已登录验证
     * @return false|void
     */
    protected function getGoogleCodeCookie($uid, $is_login = 0)
    {
        $g_secret = Cookie::get("googlesecret");
        if (empty($g_secret)) {
            return false;
        }
        $g_secret = opensslDeCode($g_secret);
        $g_secret = explode('_', $g_secret);
        if (!is_array($g_secret) || !isset($g_secret[1]) || $g_secret[1] != $uid) {
            return false;
        }

        // 验证用户是否成功登录
        if ($is_login == 1 && (!isset($g_secret[3]) || $is_login != $g_secret[3])) {
            return false;
        }

        return $g_secret;
    }

    /**
     * 检测当前控制器和方法是否匹配传递的数组
     *
     * @param array $arr 需要验证权限的数组
     * @return boolean
     */
    private function matchFuc($arr = [])
    {
        $arr = is_array($arr) ? $arr : explode(',', $arr);
        if (!$arr) {
            return FALSE;
        }
        $arr = array_map('strtolower', $arr);
        // 是否存在
        if (in_array(strtolower(Request::action()), $arr) || in_array('*', $arr)) {
            return TRUE;
        }

        // 没找到匹配
        return FALSE;
    }

    /**
     * [check_params 验证参数  参数过滤]
     * @return [return]      [合格的参数数组]
     */
    public function check_params()
    {
        if (array_key_exists(Request::action(), $this->rules)) {
            $rule      = $this->rules[Request::action()];
            $validater = new Validate($rule);
            if (!$validater->check(Request::param())) {
                return false;
            }
        }
        // 如果正确，通过验证
        return true;

    }

    static function bulidFail($message = "操作失败，请稍后再试")
    {
        return json(["code" => 1, "msg" => $message]);
    }

    static function bulidDataFail($data = [], $message = "操作失败，请稍后再试")
    {
        return json(["status" => 1, "msg" => $message, 'data' => $data]);
    }

    static function bulidSuccess($data = [], $message = "操作成功")
    {
        return json(["code" => 0, "msg" => $message, "data" => $data]);
    }

    static function bulidLoginTimeOut($message = "登录超时，请重新登录")
    {
        return json(["code" => 2, "msg" => $message]);
    }

    static function echoSuccess($data = ['st' => 0], $msg = "操作成功")
    {
        echo json_encode(["code" => 0, "data" => $data, 'msg' => $msg]);
    }

    // 公共api  ----------------------------------------------------------------------------------------

    public function signForCos()
    {
        if ($tempKeys = self::getSignForCos()) {
            return self::bulidSuccess($tempKeys);
        }
        return self::bulidFail("获取上传权限失败");
    }

    static function getSignForCos()
    {
        $configPriModel = getConfigPri();
        $sts            = new QcloudSTS();
        $config         = array(
            'url'             => 'https://sts.tencentcloudapi.com/',
            'domain'          => 'sts.tencentcloudapi.com',
            'proxy'           => '',
            'secretId'        => $configPriModel->qcloud_secretid, // 固定密钥
            'secretKey'       => $configPriModel->qcloud_secretkey, // 固定密钥
            'bucket'          => $configPriModel->cos_bucket, // 换成你的 bucket
            'region'          => $configPriModel->cos_region, // 换成 bucket 所在园区
            'durationSeconds' => 1800, // 密钥有效期
            'allowPrefix'     => "*", // 这里改成允许的路径前缀，可以根据自己网站的用户登录态判断允许上传的具体路径，例子： a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
            // 密钥的权限列表。简单上传和分片需要以下的权限，其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
            'allowActions'    => array(
                // 简单上传
                'name/cos:PutObject',
            )
        );
        $configPubModel = getConfigPub();
       // var_dump($configPubModel);
        // 获取临时密钥，计算签名
        $tempKeys = $sts->getTempKeys($config);
        if ($tempKeys) {
            $tempKeys["bucket"]   = $configPriModel->cos_bucket;
            $tempKeys["region"]   = $configPriModel->cos_region;
            $tempKeys["filename"] = date("YmdHis") . rand(10000, 99999);
            $tempKeys["imgDomain"] = isset($configPubModel->img_upload_url) ? $configPubModel->img_upload_url : "";
            return $tempKeys;
        } else {
            return null;
        }
    }

    public function getAllParams()
    {
        $where = Request::get();
        unset($where["page"]);
        unset($where["limit"]);
        foreach ($where as $key => $item) {
            if (!$item && !is_numeric($item)) {
                unset($where[$key]);
            }
        }
        return $where;
    }

    /**
     * 添加日志内容
     * @param $content 日志内容
     * @param int $uid 被操作人用户id 前台用户id
     * @return bool|int|string
     */
    protected function addAdminLog($content, $uid = 0)
    {
        if (empty($content)) {
            return true;
        }

        $data = [
            'adminid'     => $this->admin_id,
            'content'     => is_array($content) ? implode(',', $content) : $this->admin_name . $content,
            'create_time' => date('Y-m-d H:i:s'),
            'uid'         => $uid,
        ];
        return AdminLogModel::insertGetId($data);
    }

    /**
     * 获取post数据
     * @param string $name
     * @param null $default
     * @param string $filter
     * @return mixed
     */
    protected function post(string $name = '', $default = null, $filter = '')
    {
        return $this->request->post($name, $default, $filter);
    }

    /**
     * 获取get数据
     * @param string $name
     * @param bool $default
     * @param string $filter
     * @return mixed
     */
    protected function get(string $name = '', $default = null, $filter = '')
    {
        return $this->request->get($name, $default, $filter);
    }

    public function _empty()
    {
        return $this->fetch(config('app.exception_tmpl'));
    }
}